home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
choicebx.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
9KB
|
353 lines
#include "choicebx.h"
#include "formline.h"
#include <dos.h>
#define MAX_STRING 3000
ChoiceBox::ChoiceBox(rect coordinates, char* fName, char* h,
char* HOT, int POS, int START,
loc ITEMSIZE, char** ITEMSTRINGS,
int* ITEMLIST,
loc ITEMDISTANCE,
rect STATUSPOS,
int STATUSTYPE, char** STATUSSTRINGS,
int* STATUSLIST,
int res, int s, BORDERS b_type, BORDERS hdr_b_type,
int pat, int hdr_pat)
: Window(coordinates, fName, h, s, b_type, hdr_b_type, res,
pat, hdr_pat)
{
item = new Item();
hot = HOT; pos = POS; start = START; itemSize = ITEMSIZE;
itemList = ITEMLIST; itemStrings = ITEMSTRINGS;
itemDistance = ITEMDISTANCE; statusPos = STATUSPOS;
statusType = STATUSTYPE; statusStrings = STATUSSTRINGS;
statusList = STATUSLIST;
calcConsts();
}
////////////////////////
void ChoiceBox::calcConsts()
{
calcItemsNumber();
rect r = user_screen();
raw = (r.height() - itemDistance.Y)
/ (screenYT(itemSize.Y) + itemDistance.Y);
if(raw == 0)
raw = r.height() / screenYT(itemSize.Y);
column = (r.width() - itemDistance.X)
/ (screenXL(itemSize.X) + itemDistance.X);
if(column > count) // if not enough items for filling the box
column = count;
if((raw == 1 && screenYT(itemSize.Y) > r.height())
|| (screenXL(itemSize.X) + 2 * itemDistance.X > r.width())
|| (raw != 1 && screenYT(itemSize.Y) + 2 * itemDistance.Y > r.height()))
{
available = 0;
return;
}
available = 1;
}
////////////////////////////
void ChoiceBox::hide()
{
if(once && *fileName != '\0')
item->hide(getItemCoord());
Window::hide();
}
///////////////////////////
void ChoiceBox::moveTo(int number)
{
if(number == 0)
return;
item->hide(getItemCoord());
if(number < start || number > start + raw * column - 1)
{
start = pos = number;
show();
return;
}
pos = number;
item->show(getItemCoord());
showStatus(number, pattern);
}
////////////////////////////
void ChoiceBox::endOfList()
{
if(pos == count)
{
pos = 1;
start = 1;
}
else
{
pos = count;
if(count <= raw * column)
start = 0;
else
start = count - raw * column + 1;
}
}
//////////////////////////
void ChoiceBox::home()
{
item->hide(getItemCoord());
pos = start;
moveTo(pos);
}
////////////////////////
void ChoiceBox::end()
{
item->hide(getItemCoord());
if(column * raw - pos + start > count - pos)
pos = count;
else
pos = start + column * raw - 1;
moveTo(pos);
}
////////////////////////
void ChoiceBox::pgUp()
{
item->hide(getItemCoord());
if(pos >= raw * column)
pos -= raw * column;
else
pos = 1;
moveTo(pos);
}
////////////////////////
void ChoiceBox::pgDn()
{
item->hide(getItemCoord());
if(count >= pos + column * raw)
pos += column * raw;
else
pos = count;
moveTo(pos);
}
////////////////////////
void ChoiceBox::left()
{
item->hide(getItemCoord());
if(pos > 1)
pos--;
else
pos = count;
moveTo(pos);
}
////////////////////////
void ChoiceBox::right()
{
item->hide(getItemCoord());
if(count >= pos + 1)
pos++;
else
pos = 1;
moveTo(pos);
}
////////////////////////
void ChoiceBox::up()
{
item->hide(getItemCoord());
if(pos > column)
pos -= column;
else
pos = count;
moveTo(pos);
}
////////////////////////
void ChoiceBox::dn()
{
item->hide(getItemCoord());
if(count >= pos + column)
pos += column;
else
pos = 1;
moveTo(pos);
}
////////////////////////
void ChoiceBox::toTop()
{
item->hide(getItemCoord());
pos = 1;
moveTo(pos);
}
/////////////////////////
void ChoiceBox::toBottom()
{
item->hide(getItemCoord());
pos = count;
moveTo(pos);
}
/////////////////////////
int ChoiceBox::mouseOn(event e)
{
rect r = user_screen();
loc wh = e.where();
int mouse_raw = (wh.Y - r.origin.Y
- itemDistance.Y)
/ (screenYT(itemSize.Y) + itemDistance.Y);
int mouse_col = (wh.X - r.origin.X
- itemDistance.X)
/ (screenXL(itemSize.X) + itemDistance.X);
int result;
result = mouse_raw * column + mouse_col + 1;
return (result > count || result < 0) ? 0 : result;
}
/////////////////////////
rect ChoiceBox::getItemCoord()
{
rect rec = user_screen();
int position = pos - start;
int r = position / column; // first raw is 0
int c = position - r * column; // first column is 0
int left = c * (screenXL(itemSize.X) + itemDistance.X)
+ itemDistance.X;
int right = left + screenXR(itemSize.X) + 2; // + itemDistance.X);
int top = r * (screenYT(itemSize.Y) + itemDistance.Y)
+ itemDistance.Y;
int bottom = top + screenYB(itemSize.Y) + 2; // + itemDistance.Y);
return rect(rec.origin.X + left, rec.origin.Y + top,
rec.origin.X + right, rec.origin.Y + bottom);
}
//////////////////////////
void ChoiceBox::show()
{
Window::show();
// Window::clrscr();
if(!available || (itemStrings == NULL && itemList == NULL))
return;
int p = pos;
for(int i = 1; i <= raw; i++)
{
for(int j = 1; j <= column; j++)
{
pos = start + (i - 1) * column + j - 1;
showItem();
if(pos == count)
break;
}
if(pos == count)
break;
}
pos = p;
moveTo(pos);
}
///////////////////////////
void ChoiceBox::repose(rect new_coord)
{
Window::repose(new_coord);
calcConsts();
}
///////////////////////////
void ChoiceBox::exe(int act)
{
e.what = act ? KEYEVENT : NOEVENT;
switch(act)
{
case AC_LEFT: e.key = EVENT_LEFT; break;
case AC_RIGHT: e.key = EVENT_RIGHT; break;
case AC_UP: e.key = EVENT_UP; break;
case AC_DOWN: e.key = EVENT_DN; break;
case AC_PG_UP: e.key = EVENT_PG_UP; break;
case AC_PG_DN: e.key = EVENT_PG_DN; break;
case AC_CTRL_PG_UP: e.key = EVENT_CTRL_PG_UP; break;
case AC_CTRL_PG_DN: e.key = EVENT_CTRL_PG_DN; break;
case AC_CANCEL: e.key = (isRet(RET_REMOVE))
? EVENT_ALT_F3 : EVENT_ESC;
break;
case AC_OK: e.key = EVENT_F2; break;
}
int res = pos; // reserv, used if we input ESC - like command
rect r = textRect(user_screen());
mouseHideCursor();
if(!act)
hilite();
int on = 0;
mouseShowCursor();
while(1)
{
mouseShowCursor();
if(!act && !(e.what == MOUSEEVENT && !on))
get_event();
else
on = 1;
mouseHideCursor();
if(statusType) // status line
showStatus(pos, pattern);
char* ch = 0; // hot keys
if(hot != NULL
&& (ch = strchr(strlwr(hot), e.keypress())) && (e.key < 256 )
&& e.keypress())
{
moveTo(ch - hot + 1);
e.what = KEYEVENT;
e.key = EVENT_RETURN;
}
if(e.what == KEYEVENT)
switch(e.key)
{
case EVENT_F1: global_i[0] = action_type; return;
case EVENT_RIGHT: if(available) right(); break;
case EVENT_LEFT: if(available) left(); break;
case EVENT_UP: if(available) up(); break;
case EVENT_DN: if(available) dn(); break;
case EVENT_HOME: if(available) home(); break;
case EVENT_PG_UP: if(available) pgUp(); break;
case EVENT_END: if(available) end(); break;
case EVENT_PG_DN: if(available) pgDn(); break;
case EVENT_CTRL_PG_UP: if(available) toTop(); break;
case EVENT_CTRL_PG_DN: if(available) toBottom(); break;
case EVENT_ESC: if(available) moveTo(res); global_num = 0;
global_i[0] = AC_NULL; return;
case EVENT_F6:
case EVENT_F10:
case EVENT_TAB:
case EVENT_ALT_F3:
case EVENT_ALT_F4:
case EVENT_ALT_TAB:
unhilite(); global_num = pos;
global_i[0] = 0; return;
case EVENT_F2:
case EVENT_RETURN : unhilite(); global_num = pos;
global_i[0] = action_type; return;
}
else
{
if(!mouse_in(e.where()))
{
unhilite();
global_num = 0; global_i[0] = AC_NULL;
return;
} // outside of menu box
int new_pos;
if((new_pos = start + mouseOn(e) - 1) && available) // mouse pressed at the item
{
item->hide(getItemCoord());
unhilite();
e.what = KEYEVENT;
e.key = EVENT_RETURN;
global_num = new_pos;
moveTo(new_pos);
global_i[0] = action_type;
return;
}
}
if(act) // leave menu and return to the object which calls it
{ // after single processing of "act" command
global_num = pos;
return;
}
}
}
//////////////////////////